package com.edu.compile.compileresult;

import com.edu.compile.AbstractCompileResult;
import com.edu.compile.constant.NodeTypeEnum;
import com.edu.compile.dto.loop.begin.LoopBeginNodeMetadata;
import com.edu.compile.dto.loop.end.LoopEndNodeMetadata;
import com.edu.model.dto.NodeMetadata;

import java.util.ArrayList;
import java.util.List;

public class CompileLoopResult extends CompileResult {

    /**
     * 每个在for循环中的节点，都要生成节点数组，用来存放每次遍历得到的结果，例如
     * eventId:888
     * nodeId：65535
     * 生成的js代码为
     * storage['func_888_65535'] = [];
     * 在循环中每次循环都会得到该节点的结果
     * storage['func_888_65535_0'] = xxx;
     * storage['func_888_65535'].push(storage['func_888_65535_0']);
     */
    private StringBuilder INIT_NODE_STORAGE_ARRAY = new StringBuilder();

    /**
     * 记录当前正在解析的节点
     * 用来判断当前节点的节点类型
     */
    private NodeMetadata currentParseNode;

    /**
     * 记录在循环中的节点的nodeId，用来判断节点是否是循环中的节点
     * 在解析{{65535@xxx}}时，判断65535的nodeId是否是循环中的节点
     * 如果是，解析的参数要加上index后缀
     */
    private List<String> loopNodeSet = new ArrayList<>();

    /**
     * 开始节点
     */
    private LoopBeginNodeMetadata loopBeginNodeDto;

    /**
     * 结束节点
     */
    private LoopEndNodeMetadata loopEndNodeDto;

    /**
     * 部分参数和创建LoopCompileResult的CompileResult共用
     *
     * @param abstractCompileResult
     * @param loopBeginNodeDto
     */
    public CompileLoopResult(AbstractCompileResult abstractCompileResult, LoopBeginNodeMetadata loopBeginNodeDto) {
        super(abstractCompileResult);
        this.loopBeginNodeDto = loopBeginNodeDto;
//        this.scriptList = abstractCompileResult.scriptList;
//        this.dataSourceList = abstractCompileResult.dataSourceList;
//        this.innerScriptMap = abstractCompileResult.innerScriptMap;
//        this.cacheType = abstractCompileResult.cacheType;
//        this.templatePolymerization = ((CompileResult) abstractCompileResult).getTemplatePolymerization();
//        this.eventContainer = ((CompileResult) abstractCompileResult).getEventContainer();
    }

    public void loopEnd(LoopEndNodeMetadata loopEndNodeDto) {
        this.loopEndNodeDto = loopEndNodeDto;
    }

    public LoopBeginNodeMetadata getLoopBeginNodeDto() {
        return loopBeginNodeDto;
    }

    public LoopEndNodeMetadata getLoopEndNodeDto() {
        return loopEndNodeDto;
    }

    @Override
    public boolean isLoop() {
        return true;
    }

    public void putLoopNodeId(String nodeId) {
        if (!this.loopNodeSet.contains(nodeId)) {
            this.loopNodeSet.add(nodeId);
        }
    }

    public boolean isLoopNodeId(Integer nodeId) {
        return this.loopNodeSet.contains(nodeId);
    }

    public List<String> getLoopNodeSet() {
        return loopNodeSet;
    }

    public void setCurrentParseNode(NodeMetadata currentParseNode) {
        this.currentParseNode = currentParseNode;
    }

    @Override
    public boolean checkCurrentParseNode(Integer nodeType) {
        if (currentParseNode == null) {
            return super.checkCurrentParseNode(nodeType);
        } else {
            String currentNodeType = currentParseNode.getNodeType();
            if (nodeType != null) {
                if (currentNodeType.equals(nodeType)) {
                    return true;
                } else {
                    return false;
                }
            } else {
                if (NodeTypeEnum.IF_ELSE.testOr(currentNodeType, NodeTypeEnum.SWITCH)) {
                    return true;
                } else {
                    return super.checkCurrentParseNode(nodeType);
                }
            }
        }
    }

    public void putInitNodeStorageArray(String init) {
        this.INIT_NODE_STORAGE_ARRAY.append(init);
    }

//    @Override
//    public String getMainBody() {
//        String mainBody = super.getMainBody();
//        return mainBody.replace(EventConstant.LoopConstant.INIT_NODE_STORAGE_ARRAY, INIT_NODE_STORAGE_ARRAY.toString());
//    }
}
